﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Aurora.Infrastructure;
using Aurora.Infrastructure.IOC;
using Aurora.WinRegistry;
using Microsoft.Practices.Unity;

namespace Aurora.ModulesConnector
{
    public class ModuleHandler : IModuleHandler
    {
        private readonly IPathHandler _pathHandler;
        private readonly IList<AbstractModule> _modules;
        private readonly IUnityContainer _unityContainer;

        public ModuleHandler()
        {
            _unityContainer = IocFabric.CreateConfigured("workingModel");
            _pathHandler = _unityContainer.Resolve<IPathHandler>();
            _modules = new List<AbstractModule>();
        }

#region Implementation of IModuleHandler
        /// <summary>
        /// Поиск установленных модулей в папке %AppPath%\Modules
        /// </summary>
        public void Search()
        {
            var path = Path.Combine(_pathHandler.GetPath(), "Modules");
            var modNames = new List<String>();

            try
            {
                modNames.AddRange(Directory.EnumerateFiles(path, "*.dll"));
            }
            catch(DirectoryNotFoundException)
            {
                Messenger.ShowErrorMessage("Ошибка при построении списка модулей", "Папка с модулями отсутствует или указан неправильный путь к ней.");
                return;
            }
            catch (Exception)
            {
                Messenger.ShowErrorMessage("Ошибка при построении списка модулей", "Не удается составить список модулей. Проверьте наличие необходимых прав доступа.");
                return;
            }

            Load(modNames);

            return;
        }

        /// <summary>
        /// Загрузка найденных модулей
        /// </summary>
        /// <param name="modNames">Список имен модулей</param>
        private void Load(IEnumerable<string> modNames)
        {
            if (modNames == null)
            {
                return;
            }

            Assembly assembly;

            foreach (var modName in modNames)
            {
                assembly = Assembly.LoadFrom(modName);

                if (assembly.GetType("AbstractModule") == typeof(AbstractModule))
                {
                    _modules.Add(assembly.CreateInstance("AbstractModule") as AbstractModule);
                }
            }
        }

        /// <summary>
        /// Возвращает список всех доступных модулей.
        /// </summary>
        /// <returns>
        /// IList, содержащий объекты ModuleUnitAbstract.
        /// </returns>
        public IList<AbstractModule> GetList()
        {
            return _modules;
        }

        /// <summary>
        /// Включает заданный модуль
        /// </summary>
        /// <param name="moduleUnit">Имя модуля</param>
        public void PlugIn(AbstractModule moduleUnit)
        {
            moduleUnit.Activate();
        }

        /// <summary>
        /// Отключает заданный модуль
        /// </summary>
        /// <param name="moduleUnit">Имя модуля</param>
        public void PlugOut(AbstractModule moduleUnit)
        {
            moduleUnit.DeActivate();
        }
#endregion
    }
}
